Android Library 打 jar aar 混淆

Android Library 打 jar 包

正确的 library 项目的 build.gradle 中有这样的代码标志

apply plugin: 'com.android.library'

接下来就是打 Jar 包了

在需要打 Jar 的 library 项目中的 build.gradle 文件最下面也就是 dependencies {} 下面

看一个完整的示例

apply plugin: 'com.android.library'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"


    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}


task makeJar(type: Copy) {
    delete 'build/libs/' //删除已经存在的jar包
    from('build/intermediates/packaged-classes/release/') //已经帮我们打好的 jar 的路径
    into('build/libs/') //要将jar包保存的目录
    include('classes.jar')//设置过滤,只打包classes文件
    rename('classes.jar', 'mylibrary.jar')//重命名,mylibrary.jar 根据自己的需求设置
}
makeJar.dependsOn(build)

接下来就是执行命令

mac : 在当前项目的根目录下执行

./gradlew makeJar

然后等待编译成功之后,就可以在前面指定的目录中看到我们想要的 jar 包了。

Jar 包混淆

有时候我们打出来的 Jar 想将代码混淆,该怎么做呢?

这个时候我们还是再 library 项目的 build.gradle 的文件中做文章。

看改动如下

apply plugin: 'com.android.library'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"


    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

task makeJar(type: proguard.gradle.ProGuardTask, dependsOn: "build") {
    injars 'build/intermediates/packaged-classes/release/classes.jar'
    outjars 'build/outputs/modify.jar'
    configuration 'proguard-rules.pro'
}

通过对比,不难发现,其实改动的只是 task makeJar()方法
其实只是在原有的 jar 上加了混淆,也就是引入了这样的代码

configuration 'proguard-rules.pro'

也就是我们的混淆文件

至于proguard-rules.pro里面的内容就需要我们自己根据项目中的内容去写了

1.首先可以把AndroidStudio 自带的标准内容写入,如下:

#表示混淆时不使用大小写混合类名
-dontusemixedcaseclassnames
#表示不跳过library中的非public的类
-dontskipnonpubliclibraryclasses
#打印混淆的详细信息
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
##表示不进行校验,这个校验作用 在java平台上的
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <methods>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <fields>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <init>(...);
}

2.一般都需要的如下(其中 xxx 替换成你自己本地的相关路径)

#引入依赖包rt.jar(jdk路径)
-libraryjars /xxx/jdk1.8.0_144.jdk/Contents/Home/jre/lib/rt.jar
#引入依赖包android.jar(android SDK路径)
-libraryjars /xxx/Android/sdk/platforms/android-29/android.jar

#忽略警告
-ignorewarnings
#保证是独立的jar,没有任何项目引用,如果不写就会认为我们所有的代码是无用的,从而把所有的代码压缩掉,导出一个空的jar
-dontshrink
#保护泛型
-keepattributes Signature

3.最后加上我们不希望被混淆的类或者方法(根据自己的实际需求添加,比如入口什么的)

# 不希望被混淆的类
-keep class com.cml.lib.M
# 不希望被混淆的方法
-keep class com.cml.lib.M {
    void a(...);
}    

好了,接下来再次再项目的根目录执行命令

./gradlew makeJar

然后等待编译完成,看看输出出来的 Jar 就已经被混淆过了。

打 aar 包

aar 相对于 Jar 来说可以携带更多的东西,比如资源文件、Manifest文件等。

aar 的生成就简单多了,用 AndroidStudio 就可以帮我们完成。

点 AndroidStudio 右上角有一个 Gradle(竖这放的)–> 项目名 –> library 名–> Tasks –> build –> assemble , 双击最后的这个 assemble 就完成了

aar 的输出路径在 library 的 build/outputs/aar/ 下面 会发现有debug和 release 两个版本,取自己需要的就行了,如果不知道需要什么,那么取 release 版本即可

但是我们查看发现这个 aar 并没有被混淆,那么怎么混淆呢?

其实跟我们 apk 的混淆一样了,有一个开关需要打开在 library 的 build.gradle 中

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

对,就是这个minifyEnabled设置为 true 即可打开混淆了。

但同样不要忘记proguard-rules.pro文件里面的内容的编写哦,具体的编写方法,上面已经说过了,跟前面的 Jar 混淆方式一样。